﻿#region Copyright ©2008-2009, Technische Universitaet Muenchen
// ====================================================================================================
//
// Last Changed by       $Author: then $
// Last Changed Date     $LastChangedDate: 2009-06-15 08:45:45 +0200 (Mon, 15 Jun 2009) $
// Last Changed Revision $Rev: 194 $
//
// ====================================================================================================
#endregion

using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;

namespace Tum.CollabXT.Wizard
{
    /// <summary>
    /// A conversion project.
    /// </summary>
    internal class ConversionProject
    {
        /// <summary>
        /// Project file of the current project.
        /// </summary>
        string ProjectFile;

        /// <summary>
        /// Gets or sets the used process provider.
        /// </summary>
        public ProcessProviderInfo ProcessProvider
        {
            get { return _ProcessProvider; }
            set { _ProcessProvider = value; }
        }
        ProcessProviderInfo _ProcessProvider;

        /// <summary>
        /// Gets a list of the tool providers, which will be used.
        /// </summary>
        public List<ToolProviderInfo> ToolProviders
        {
            get { return _ToolProviders; }
        }
        List<ToolProviderInfo> _ToolProviders = new List<ToolProviderInfo>();


        /// <summary>
        /// Constructor.
        /// </summary>
        public ConversionProject()
        { }

        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="projectFile">Project file to be loaded.</param>
        /// <param name="pluginManager">Plugin manager to be used.</param>
        public ConversionProject(string projectFile, PluginManager pluginManager)
        {
            if (!File.Exists(projectFile))
                throw new CxtWizardException("Project file does not exist");

            ProjectFile = projectFile;
            Load(pluginManager);
        }

        /// <summary>
        /// Load the current project from a project file.
        /// </summary>
        /// <param name="pluginManager">Plugin manager to be used.</param>
        private void Load(PluginManager pluginManager)
        {
            XmlReader xmlReader = XmlReader.Create(ProjectFile);
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(xmlReader);

            XmlNode projectNode = xmlDoc.SelectSingleNode("PETproject");
            if(projectNode == null)
                projectNode = xmlDoc.SelectSingleNode("CollabXTproject"); //Legacy compatibility
            if (projectNode != null)
            {
                XmlNode processProviderNode = projectNode.SelectSingleNode("processprovider");
                if (processProviderNode != null)
                {
                    try
                    {
                        string pluginFile = processProviderNode.Attributes["plugin"].Value;
                        foreach (ProcessProviderInfo curPP in pluginManager.GetProcessProviders())
                        {
                            if (Helper.FileNameFromPath(curPP.AssemblyPath).Equals(pluginFile, StringComparison.OrdinalIgnoreCase))
                            {
                                ProcessProvider = curPP;
                                try
                                {
                                    curPP.Instance.Deserialize(processProviderNode);
                                }
                                catch { }
                                break;
                            }
                        }
                    }
                    catch { }
                }

                XmlNode toolProvidersNode = projectNode.SelectSingleNode("toolproviders");
                if (toolProvidersNode != null)
                {
                    XmlNodeList tpNodes = toolProvidersNode.SelectNodes("toolprovider");
                    foreach (XmlNode curTPNode in tpNodes)
                    {
                        string pluginFile = curTPNode.Attributes["plugin"].Value;
                        foreach (ToolProviderInfo curTP in pluginManager.GetToolProviders())
                        {
                            if (Helper.FileNameFromPath(curTP.AssemblyPath).Equals(pluginFile, StringComparison.OrdinalIgnoreCase))
                            {
                                ToolProviders.Add(curTP);
                                try
                                {
                                    curTP.Instance.Deserialize(curTPNode);
                                }
                                catch { }
                                break;
                            }
                        }
                    }
                }
            }

            xmlReader.Close();
        }

        /// <summary>
        /// Saves the current project to a project file.
        /// </summary>
        /// <param name="outputFile">Output project file path and name.</param>
        public void Save(string outputFile)
        {
            if(ProjectFile == null && (outputFile == null || outputFile.Length == 0))
                throw new CxtWizardException("You must specify an output file.");

            if(outputFile != null)
                ProjectFile = outputFile;

            //Create file
            XmlWriter xmlWriter = XmlWriter.Create(ProjectFile);
            XmlDocument xmlDoc = new XmlDocument();

            //Main node
            XmlNode projectNode = xmlDoc.CreateElement("PETproject");
            xmlDoc.AppendChild(projectNode);

            #region Write process provider
            if (ProcessProvider != null)
            {
                XmlNode processProviderNode = xmlDoc.CreateElement("processprovider");
                projectNode.AppendChild(processProviderNode);

                XmlAttribute ppPathAttribute = xmlDoc.CreateAttribute("plugin");
                ppPathAttribute.Value = Helper.FileNameFromPath(ProcessProvider.AssemblyPath);
                processProviderNode.Attributes.Append(ppPathAttribute);

                try
                {
                    ProcessProvider.Instance.Serialize(processProviderNode);
                }
                catch { }
            }
            #endregion


            #region Save tool providers
            XmlNode toolProvidersNode = xmlDoc.CreateElement("toolproviders");
            projectNode.AppendChild(toolProvidersNode);

            foreach (ToolProviderInfo curToolProvider in ToolProviders)
            {
                XmlNode curToolProviderNode = xmlDoc.CreateElement("toolprovider");
                toolProvidersNode.AppendChild(curToolProviderNode);

                XmlAttribute tpPathAttribute = xmlDoc.CreateAttribute("plugin");
                tpPathAttribute.Value = Helper.FileNameFromPath(curToolProvider.AssemblyPath);
                curToolProviderNode.Attributes.Append(tpPathAttribute);

                try
                {
                    curToolProvider.Instance.Serialize(curToolProviderNode);
                }
                catch { }
            }
            #endregion


            //Close file
            xmlDoc.Save(xmlWriter);
            xmlWriter.Close();
        }
    }
}